#include <stdlib.h>
#include "CircleBuffer.h"


/*
 *串口发送缓冲区定义
 */
char Uart1TxdBuffer[UART1_TXD_BUFF_ROW_SUM][UART1_TXD_BUFF_ROW_SIZE];    //缓冲区数组
struct CircleBuffer Uart1TxdCirclebuff={                  //缓冲区变量
    (char *)Uart1TxdBuffer,		//缓冲区数组
    UART1_TXD_BUFF_ROW_SUM,		//缓冲区行数
    UART1_TXD_BUFF_ROW_SIZE,		//缓冲区行大小
    0,							//下次读取的行下标
    0,							//下次写入的行下标
    0,							//还未读取的行数
    2,							//下次写入行的下次写入的位置，0号位留给数据长度
};
char Uart5TxdBuffer[UART5_TXD_BUFF_ROW_SUM][UART5_TXD_BUFF_ROW_SIZE];    //缓冲区数组
struct CircleBuffer Uart5TxdCirclebuff={                  //缓冲区变量
        (char *)Uart5TxdBuffer,		//缓冲区数组
        UART5_TXD_BUFF_ROW_SUM,		//缓冲区行数
        UART5_TXD_BUFF_ROW_SIZE,		//缓冲区行大小
        0,							//下次读取的行下标
        0,							//下次写入的行下标
        0,							//还未读取的行数
        2,							//下次写入行的下次写入的位置，0号位留给数据长度
};


/*
 *串口接收缓冲区定义
 */
char Uart1RxdBuffer[UART1_RXD_BUFF_ROW_SUM][UART1_RXD_BUFF_ROW_SIZE];    //缓冲区数组
struct CircleBuffer Uart1RxdCirclebuff={                  //缓冲区变量
    (char *)Uart1RxdBuffer,		//缓冲区数组
    UART1_RXD_BUFF_ROW_SUM,		//缓冲区行数
    UART1_RXD_BUFF_ROW_SIZE,		//缓冲区行大小
    0,							//下次读取的行下标
    0,							//下次写入的行下标
    0,							//还未读取的行数
    2,							//下次写入行的下次写入的位置，0 1号位留给数据长度
};
char Uart5RxdBuffer[UART5_RXD_BUFF_ROW_SUM][UART5_RXD_BUFF_ROW_SIZE];    //缓冲区数组
struct CircleBuffer Uart5RxdCirclebuff={                  //缓冲区变量
        (char *)Uart5RxdBuffer,		//缓冲区数组
        UART5_RXD_BUFF_ROW_SUM,		//缓冲区行数
        UART5_RXD_BUFF_ROW_SIZE,		//缓冲区行大小
        0,							//下次读取的行下标
        0,							//下次写入的行下标
        0,							//还未读取的行数
        2,							//下次写入行的下次写入的位置，0 1号位留给数据长度
};


char WriteLogBuffer[WRITE_LOG_BUFF_ROW_SUM][WRITE_LOG_BUFF_ROW_SIZE];    //缓冲区数组
struct CircleBuffer WriteLogCirclebuff={                  //缓冲区变量
        (char *)WriteLogBuffer,		//缓冲区数组
        WRITE_LOG_BUFF_ROW_SUM,		//缓冲区行数
        WRITE_LOG_BUFF_ROW_SIZE,		//缓冲区行大小
        0,							//下次读取的行下标
        0,							//下次写入的行下标
        0,							//还未读取的行数
        2,							//下次写入行的下次写入的位置，0 1号位留给数据长度
};



/*
 *功能：向环型缓冲区写入一条数据
 *输入：circleBuffer->环型缓冲区变量 data->要写入的数据 size->数据大小
 *输出：未读的行数（数据条数）
 */
unsigned int WriteCircleBuff(struct CircleBuffer *circleBuffer,char *data,unsigned int size ){

    if(size > circleBuffer->RowSize-2)    //如果写入的数据大于缓冲区的行大小，-2是因为前两个位置是留着写数据大小的，供读的时候使用
        return -1;
    if(circleBuffer->UnReadRowSum >= circleBuffer->RowSum)  //如果缓冲区已满
        return -2;
    circleBuffer->UnReadRowSum++;    //未读的行数加一

	
    char *pWrite=circleBuffer->pBuffer+circleBuffer->RowSize*circleBuffer->NextWriteRowIdx; //求出下次写入位置的行首地址
    *pWrite++=size/256;   //行首写入数据大小，表示后面的字节数
    *pWrite++=size%256;

    while(size--){  //写入数据
        *pWrite++=*data++;
    }

    circleBuffer->NextWriteRowIdx++; //下次写入的位置加一
    if(circleBuffer->NextWriteRowIdx > circleBuffer->RowSum-2)  //如果大于最大行号
        circleBuffer->NextWriteRowIdx=0; //返回首行


    return circleBuffer->UnReadRowSum;   //返回未读的行数


}
/*
 *功能：向环型缓冲区下一写入行的下一写入位置写入一个字节
 *输入：circleBuffer->环型缓冲区变量 data->要写入的数据（一个字节）
 *输出：写入的位置
 */
unsigned int WriteOnebyteToCircleBuff(struct CircleBuffer *circleBuffer,unsigned char data){

    if(circleBuffer->NextWriteIdxInRow > circleBuffer->RowSize-2)    //如果写入的位置超出缓冲区
        return -1;
    if(circleBuffer->UnReadRowSum >= circleBuffer->RowSum)  //如果缓冲区已满
        return -2;

    char *pWrite=circleBuffer->pBuffer+circleBuffer->RowSize*circleBuffer->NextWriteRowIdx; //求出下次写入位置的行首地址

	*(pWrite+circleBuffer->NextWriteIdxInRow++)=data;   //写入数据

    return circleBuffer->NextWriteIdxInRow-2;   //返回写入的位置
}

/*
 *功能：保存逐个字节写入的下一行，并指向下次写入行
 *输入：circleBuffer->环型缓冲区变量
 *输出：未读的行数
 */
unsigned int SaveRowAndToNextRow(struct CircleBuffer *circleBuffer){

    unsigned int size = circleBuffer->NextWriteIdxInRow-2;  //求出之前逐个字节写入的字节总数，-1是因为起点位置是1

	if(size == 0)
		return -3;
    if(size > circleBuffer->RowSize-2)    //如果写入的字节过多，一般写入的时候也有保存，这里再次判断
        return -1;
    if(circleBuffer->UnReadRowSum >= circleBuffer->RowSum)  //如果缓冲区已满
        return -2;

	//printf("size = %u\n",size);

    char *pWrite=circleBuffer->pBuffer+circleBuffer->RowSize*circleBuffer->NextWriteRowIdx; //求出下次写入位置的行首地址

	//printf("size=%d\n",size);	//调试用
	*pWrite++=size/256;   //行首写入数据大小，表示后面的字节数
	*pWrite=size%256;
	
    circleBuffer->UnReadRowSum++;    //未读的行数++
   // printf("circleBuffer->UnReadRowSum=%d\n",circleBuffer->UnReadRowSum);	//调试用

    circleBuffer->NextWriteRowIdx++; //下次写入的位置++
    if(circleBuffer->NextWriteRowIdx > circleBuffer->RowSum-2)  //如果大于最大行号
        circleBuffer->NextWriteRowIdx=0; //返回首行

	circleBuffer->NextWriteIdxInRow=2;	//下次写入行的下次写入的位置回到起始位置
	
//	printf("circleBuffer->NextWriteRowIdx=%d\n",circleBuffer->NextWriteRowIdx);	//调试用


    return circleBuffer->UnReadRowSum;   //返回未读的行数
}

/*
 *功能：清除逐个字节写入的下一行
 *输入：circleBuffer->环型缓冲区变量
 *输出：未读的行数
 */
unsigned int ClearNextRow(struct CircleBuffer *circleBuffer){

	circleBuffer->NextWriteIdxInRow=2;	//下次写入行的下次写入的位置回到起始位置

    return circleBuffer->UnReadRowSum;   //返回未读的行数
}





/*
 *功能：从环型缓冲区读出数据
 *输入：circleBuffer->环型缓冲区变量 readBuff->临时存放在数组 readBuffSize->临时存放数组的大小
 *输出：未读的行数（数据条数）
 */
unsigned int ReadCircleBuff_ToBuff(struct CircleBuffer *circleBuffer,char *readBuff,unsigned int readBuffSize ){

    char *pRead=circleBuffer->pBuffer+circleBuffer->RowSize*circleBuffer->NextReadRowIdx; //求出下次写入位置的行首地址
    unsigned char size=*pRead+2;  //读出本行的数据量（+2是表示包括行首两个表示数据大小的字节）

    if(readBuffSize < size)    //如果读出的缓冲数组大小小于该行的数据大小
        return -1;
    if(circleBuffer->UnReadRowSum <= 0)  //如果没有未读的行
        return -2;

	if(circleBuffer->UnReadRowSum > 0)
    	circleBuffer->UnReadRowSum--;    //未读的行数减一


    while(size--){  //写入数据
        *readBuff++=*pRead++;
    }
    


    circleBuffer->NextReadRowIdx++; //下次写入的位置加一
    if(circleBuffer->NextReadRowIdx > circleBuffer->RowSum-2)  //如果大于最大行号
        circleBuffer->NextReadRowIdx=0; //返回首行


    return circleBuffer->UnReadRowSum;   //返回未读的行数


}


/*
 *功能：从环型缓冲区读出数据
 *输入：circleBuffer->环型缓冲区变量
 *输出：返回该行的首地址，而且行首的数据表示后面数据的大小
 */
char* ReadCircleBuff_ReturnAddr(struct CircleBuffer *circleBuffer){

	//printf("circleBuffer->UnReadRowSum=%d\n",circleBuffer->UnReadRowSum);
	if(circleBuffer->UnReadRowSum <= 0)  //如果没有未读的行
			return NULL;
	//printf("circleBuffer->UnReadRowSum=%d\n",circleBuffer->UnReadRowSum);	//调试用

    char *pRead=circleBuffer->pBuffer+circleBuffer->RowSize*circleBuffer->NextReadRowIdx; //求出下次写入位置的行首地址

	if(circleBuffer->UnReadRowSum > 0)
    	circleBuffer->UnReadRowSum--;    //未读的行数减一


    circleBuffer->NextReadRowIdx++; //下次写入的位置加一
    if(circleBuffer->NextReadRowIdx > circleBuffer->RowSum-2)  //如果大于最大行号
        circleBuffer->NextReadRowIdx=0; //返回首行


    return pRead;   //返回本行首地址


}

unsigned int GetThisRowDataLen(unsigned char* pRead)
{
	return *pRead*256+*(pRead+1);
}

void CleanAllUnReadRow(struct CircleBuffer *circleBuffer)
{
	circleBuffer->UnReadRowSum = 0;    //未读的行数置0
	circleBuffer->NextReadRowIdx = circleBuffer->NextWriteRowIdx; 
	circleBuffer->NextWriteIdxInRow=2;	//下次写入行的下次写入的位置回到起始位置
}



